package com.lushixiang.controller.user;


import com.lushixiang.dto.request.UserRegistDto;
import com.lushixiang.dto.request.UserSignInDTO;
import com.lushixiang.dto.response.AllUserResDto;
import com.lushixiang.dto.response.UserInfoDto;
import com.lushixiang.facade.UserFacade;
import com.lushixiang.mybatis.entity.user.UserEntity;
import com.lushixiang.service.user.UserService;
import com.lushixiang.token.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import com.lushixiang.base.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;

import static com.lushixiang.StaticVariables.tokenLastTime;
import static com.lushixiang.enums.CommonRespEnum.*;

@Slf4j
@Component
public class UserController implements UserFacade {

    @Autowired
    UserService userService;

    @Override
    public BaseResponse<Map<String,String>> signIn(UserSignInDTO userSignInDTO){
        BaseResponse response = new BaseResponse<HashMap<String,String>>();
        BaseResHead head = new BaseResHead();

        // 判断DTO对象的非空
        if(userSignInDTO.getEmailAddr()==null || userSignInDTO.getPassword()==null){
            head.setResCode(USER_SIGN_FAIL.getCode());
            head.setResMsg(USER_SIGN_FAIL.getMsg());
            response.setResHead(head);
            log.info("用户{}使用密码{}进行登录失败",userSignInDTO.getEmailAddr(),userSignInDTO.getPassword());
            return response;
        }
        if(userService.userSignIn(userSignInDTO.getEmailAddr(),userSignInDTO.getPassword())){
            String token = TokenUtil.generateToken(userSignInDTO.getEmailAddr(),tokenLastTime);
            head.setResCode(WELL_DONE.getCode());
            head.setResMsg(WELL_DONE.getMsg());
            response.setResHead(head);
            HashMap<String, String> map = new HashMap<>();
            map.put("token",token);
            // 查出用户名和用户ID
            UserEntity userEntity = userService.queryUserInfo(userSignInDTO.getEmailAddr());
            map.put("userName", userEntity.getUserName());
            map.put("iconPath", userEntity.getIconPath());
            response.setResBody(map);
            log.info("用户{}使用密码{}登录成功获得token: {}",userSignInDTO.getEmailAddr(),userSignInDTO.getPassword(),token);
        }else {
            head.setResCode(USER_SIGN_FAIL.getCode());
            head.setResMsg(USER_SIGN_FAIL.getMsg());
            response.setResHead(head);
            log.info("用户{}使用密码{}进行登录失败",userSignInDTO.getEmailAddr(),userSignInDTO.getPassword());
        }

        return response;
    }

    @Override
    public BaseResponse<String> applyResetPassword(String emailAddr) {
        BaseResponse<String> response = new BaseResponse<String>();
        BaseResHead head = new BaseResHead();
        // 验证邮箱是否有效（存在不为空）
        if(emailAddr == null || emailAddr.length()==0){
            head.setResCode(EMAIL_IS_EMPTY.getCode());
            head.setResMsg(EMAIL_IS_EMPTY.getMsg());
            response.setResHead(head);
            log.info("验证邮箱{}无效不存在或者为空",emailAddr);
            return response;
        }
        // 验证邮箱是否有效（邮箱已存在）
        if(!userService.isEmailRegisted(emailAddr)){
            head.setResCode(EMAIL_IS_VAILD.getCode());
            head.setResMsg(EMAIL_IS_VAILD.getMsg());
            response.setResHead(head);
            log.info("验证邮箱{}不存在",emailAddr);
            return response;
        }

        if(!userService.applyEmailAddrCheck(emailAddr)){
            head.setResCode(EMAIL_SENT_ERR.getCode());
            head.setResMsg(EMAIL_SENT_ERR.getMsg());
            response.setResHead(head);
            log.info("邮箱{}发送邮件过程出错",emailAddr);
            return response;
        }
        head.setResCode(WELL_DONE.getCode());
        head.setResMsg(WELL_DONE.getMsg());
        response.setResHead(head);
        log.info("邮箱{}发送邮件过程成功",emailAddr);
        return response;
    }

    @Override
    public BaseResponse<String> resetPassword(String token, String emailAddr, String password){
        BaseResponse<String> response = new BaseResponse<>();
        BaseResHead head = new BaseResHead();

        if(!Objects.equals(TokenUtil.getTokenAudience(token), emailAddr)){
            head.setResCode(ILLEGAL_IMPROVE_POWER.getCode());
            head.setResMsg(ILLEGAL_IMPROVE_POWER.getMsg());
            response.setResHead(head);
            log.info("邮箱{}更新用户过程失败",emailAddr);
            return response;
        }
        log.info("验证通过，开始更新用户密码");
        if(!userService.changePaswdByEmailAdd(emailAddr,password)){
            head.setResCode(UNKONW_SYSTEM_ERROR.getCode());
            head.setResMsg(UNKONW_SYSTEM_ERROR.getMsg());
            response.setResHead(head);
            log.info("邮箱{}更新用户过程失败",emailAddr);
            return response;
        }
        head.setResCode(WELL_DONE.getCode());
        head.setResMsg(WELL_DONE.getMsg());
        response.setResHead(head);
        log.info("邮箱{}更新用户过程成功",emailAddr);

        return response;
    }

    // 查询用户详细信息
    @Override
    public BaseResponse<UserInfoDto> queryUserInfo(String emailAddr) {

        log.info("查询emailAddr:{} 详细信息",emailAddr);
        BaseResponse<UserInfoDto> response = new BaseResponse<>();
        BaseResHead head = new BaseResHead();
        UserInfoDto userInfoDto = new UserInfoDto();
        UserEntity userEntity = userService.queryUserInfo(emailAddr);
        log.info("查询到用户详细信息{}",userEntity);


        userInfoDto.setUserName(userEntity.getUserName());
        userInfoDto.setEmailAddr(userEntity.getEmailAddr());
        userInfoDto.setIconPath(userEntity.getIconPath());

        head.setResCode(WELL_DONE.getCode());
        head.setResMsg(WELL_DONE.getMsg());

        response.setResHead(head);
        response.setResBody(userInfoDto);

        return response;
    }

    @Override
    // 设置修改用户icon
    public BaseResponse<String> modifyIcon(MultipartFile file, String emailAddr, String token) {
        BaseResponse<String> response = new BaseResponse<>();
        BaseResHead head = new BaseResHead();

        // 判断用户修改icon权限
        if(!Objects.equals(emailAddr, TokenUtil.getTokenAudience(token))){
            log.info("用户{}与token验证后不成功,非法越权将返回重新登录",emailAddr );
            head.setResCode(REQUEST_WITHOUT_SIGN.getCode());
            head.setResMsg(REQUEST_WITHOUT_SIGN.getMsg());
            response.setResHead(head);
            return response;
        }
        // 调用修改icon服务
        if(!userService.modifyUserIcon(file,emailAddr)){
            log.info("用户{}上传自定义icon失败,将返回上传失败",emailAddr );
            head.setResCode(UPLOAD_ERROR.getCode());
            head.setResMsg(UPLOAD_ERROR.getMsg());
            response.setResHead(head);
        }
        head.setResCode(WELL_DONE.getCode());
        head.setResMsg(WELL_DONE.getMsg());
        response.setResHead(head);
        return response;
    }

    @Override
    public BaseResponse<String> deregistration(UserRegistDto dto) {
        BaseResponse<String> response = new BaseResponse<>();
        BaseResHead head = new BaseResHead();

        // 申请验证验证码
        if(!userService.applyCheckEmailAddr(dto.getEmailAddr(),dto.getCheckCode())){
            head.setResCode(EMAIL_CHECK_FAIL.getCode());
            head.setResMsg(EMAIL_CHECK_FAIL.getMsg());
            response.setResHead(head);
            log.info("用户验证码{}不正确,返回信息{}",dto.getCheckCode(),response);
            return response;
        }
        if(!userService.isEmailRegisted(dto.getEmailAddr())){
            head.setResCode(EMAIL_IS_INVAILD.getCode());
            head.setResMsg(EMAIL_IS_INVAILD.getMsg());
            response.setResHead(head);
            log.info("用户验证码{}不通过,返回信息{}",dto.getCheckCode(),response);
            return response;
        }
        log.info("验证通过，开始用户销户");
        if(!userService.userDeregist(dto.getEmailAddr())){
            head.setResCode(UNKONW_SYSTEM_ERROR.getCode());
            head.setResMsg(UNKONW_SYSTEM_ERROR.getMsg());
            response.setResHead(head);
            log.info("用户验证码{}通过，创建用户{}过程失败,返回信息{}",dto.getCheckCode(),dto.getUserName(),response);
            return response;
        }
        // 一切正常
        head.setResCode(WELL_DONE.getCode());
        head.setResMsg(WELL_DONE.getMsg());
        response.setResHead(head);
        return response;
    }


    @Override
    public String index() {

        return "<!DOCTYPE html>\n" +
                "<html>\n" +
                "<body>\n" +
                "\n" +
                "<a href=\"http://www.beian.miit.gov.cn\" target = \"_blank\"\">皖 ICP 备 2022000606 号</a>"+
                "</body>\n" +
                "</html>";
    }

    // 用户申请邮箱验证码发送
    @Override
    public BaseResponse<String> sentUserCode(Map<String,String> req){
        String emailAddr = req.get("emailAddr");

        BaseResponse<String> response = new BaseResponse<>();
        BaseResHead head = new BaseResHead();

        //校验邮箱不为空
        if(emailAddr==null){
            log.info("用户填报邮箱地址为空");
            head.setResCode(EMAIL_IS_EMPTY.getCode());
            head.setResMsg(EMAIL_IS_EMPTY.getMsg());
            response.setResHead(head);
            return response;
        }
//        // 校验邮箱是否可验证
//        if(userService.isEmailRegisted(emailAddr)){
//            log.info("用户填报邮箱地址已被注册");
//            head.setResCode(EMAIL_IS_INVAILD.getCode());
//            head.setResMsg(EMAIL_IS_INVAILD.getMsg());
//            response.setResHead(head);
//            return response;
//        }

        // 尝试邮箱验证
        if(!userService.applyEmailAddrCheck(emailAddr)){
            head.setResCode(EMAIL_SENT_ERR.getCode());
            head.setResMsg(EMAIL_SENT_ERR.getMsg());
            response.setResHead(head);
            log.info("邮件{}发送失败,返回信息{}",emailAddr,response);
            return response;
        }

        // 一切正常
        head.setResCode(WELL_DONE.getCode());
        head.setResMsg(WELL_DONE.getMsg());
        response.setResHead(head);
        return response;
    }

    // 用户提交验证码及相关信息进行注册
    @Override
    public BaseResponse<String> signUp(UserRegistDto dto){
        BaseResponse<String> response = new BaseResponse<>();
        BaseResHead head = new BaseResHead();

        // 申请验证验证码
        if(!userService.applyCheckEmailAddr(dto.getEmailAddr(),dto.getCheckCode())){
            head.setResCode(EMAIL_CHECK_FAIL.getCode());
            head.setResMsg(EMAIL_CHECK_FAIL.getMsg());
            response.setResHead(head);
            log.info("用户验证码{}不正确,返回信息{}",dto.getCheckCode(),response);
            return response;
        }
        if(userService.isEmailRegisted(dto.getEmailAddr())){
            head.setResCode(EMAIL_IS_INVAILD.getCode());
            head.setResMsg(EMAIL_IS_INVAILD.getMsg());
            response.setResHead(head);
            log.info("用户验证码{}通过，创建用户{}过程失败,返回信息{}",dto.getCheckCode(),dto.getUserName(),response);
            return response;
        }
        log.info("验证通过，开始用户创建");
        if(!userService.userRegist(dto.getUserName(),dto.getPassword(), dto.getCheckCode(), dto.getEmailAddr(), "00")){
            head.setResCode(UNKONW_SYSTEM_ERROR.getCode());
            head.setResMsg(UNKONW_SYSTEM_ERROR.getMsg());
            response.setResHead(head);
            log.info("用户验证码{}通过，创建用户{}过程失败,返回信息{}",dto.getCheckCode(),dto.getUserName(),response);
            return response;
        }
        // 一切正常
        head.setResCode(WELL_DONE.getCode());
        head.setResMsg(WELL_DONE.getMsg());
        response.setResHead(head);
        return response;
    }

    @Override
    public BaseResponse<String> restPasswordByEmailCheck(UserRegistDto dto) {
        BaseResponse<String> response = new BaseResponse<>();
        BaseResHead head = new BaseResHead();
        String emailAddr = dto.getEmailAddr();
        String password = dto.getPassword();
        if(emailAddr==null || Objects.equals(emailAddr,"")){
            log.info("传入用户不存在，验证邮箱为空");
            head.setResCode(EMAIL_IS_EMPTY.getCode());
            head.setResMsg(EMAIL_IS_EMPTY.getMsg());
            response.setResHead(head);
            return response;
        }

        if(password==null || Objects.equals(password,"")){
            log.info("传入用户重置密码不存在或为空");
            head.setResCode(PASSWORD_IS_EMPTY.getCode());
            head.setResMsg(PASSWORD_IS_EMPTY.getMsg());
            response.setResHead(head);
            return response;
        }
        if(!userService.isEmailRegisted(emailAddr)){
            log.info("用户不存在，不可以修改密码");
            head.setResCode(EMAIL_IS_VAILD.getCode());
            head.setResMsg(EMAIL_IS_VAILD.getMsg());
            response.setResHead(head);
            return response;

        }
        // 申请验证验证码
        if(!userService.applyCheckEmailAddr(dto.getEmailAddr(),dto.getCheckCode())){
            head.setResCode(EMAIL_CHECK_FAIL.getCode());
            head.setResMsg(EMAIL_CHECK_FAIL.getMsg());
            response.setResHead(head);
            log.info("用户验证码{}不正确,返回信息{}",dto.getCheckCode(),response);
            return response;
        }
        log.info("验证通过，开始更新用户密码");

        if(!userService.changePaswdByEmailAdd(emailAddr,password)){
            head.setResCode(UNKONW_SYSTEM_ERROR.getCode());
            head.setResMsg(UNKONW_SYSTEM_ERROR.getMsg());
            response.setResHead(head);
            log.info("邮箱{}更新用户过程失败",emailAddr);
            return response;
        }
        head.setResCode(WELL_DONE.getCode());
        head.setResMsg(WELL_DONE.getMsg());
        response.setResHead(head);
        log.info("邮箱{}更新用户过程成功",emailAddr);

        return response;
    }

    // 测试用API
    @Override
    public BaseResponse<AllUserResDto> getUserTableAll(){
        // 创建返回信息
        BaseResponse<AllUserResDto> response = new BaseResponse<>();
        AllUserResDto body = new AllUserResDto();
        BaseResHead head = new BaseResHead();

        head.setResCode(WELL_DONE.getCode());
        head.setResMsg(WELL_DONE.getMsg());

        // 获取信息
        List<String> users = new ArrayList<>();
        try{
            userService.selectAllUser().stream().forEach(x->users.add(x.toString()));
        }catch (Exception e){
            head.setResCode(UNKONW_SYSTEM_ERROR.getCode());
            head.setResMsg(UNKONW_SYSTEM_ERROR.getMsg());

            body.setUsers(null);
            response.setResBody(body);
            response.setResHead(head);
            return response;

        }

        // 丰富response
        body.setUsers(users);
        response.setResBody(body);
        response.setResHead(head);




        return response;
    }
}
